#include <stdio.h>
#include <stddef.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>


#include "../includes/erproc.h"

void Listen(int socket, int backlog){
    if (listen(socket, backlog) == -1){
        perror("FAILED LISTEN");
        exit(EXIT_FAILURE);
    }
}


void Select(int nfds, fd_set *__restrict__ readfds){
    if (select(nfds, readfds, NULL, NULL, NULL) == -1){
        perror("FAILED SELECT");
        exit(EXIT_FAILURE);
    }
}


void Getaddrinfo(const char *__restrict__ node, 
                 const char *__restrict__ service,
                 const struct addrinfo *__restrict__ hints,
                 struct addrinfo **__restrict__ res)
{
    int rv;
    if ((rv = getaddrinfo(node, service, hints, res)) != 0){
        fprintf(stderr, "SELECTSERVER: %s\n", gai_strerror(rv));
        exit(EXIT_FAILURE);
    }
}


void Send(int socket, const void *buf, size_t len){
    if (send(socket, buf, len, 0) == -1){
        perror("FAILED SEND");
        exit(EXIT_FAILURE);
    }
}


void Recv(int socket, void *buf, size_t len){
    if (recv(socket, buf, len, 0) == -1){
        perror("FAILED RECV");
        exit(EXIT_FAILURE);
    }
}


int Accept(int socket, struct sockaddr *restrict address, 
           socklen_t *restrict address_len)
{
    int newfd;

    newfd = accept(socket, address, address_len);

    if (newfd == -1){
        perror("ACCEPT FAILED");
        Close(newfd);
    }
    else
        return newfd;
}


void Close(int fd){
    if (close(fd) == -1){
        perror("FAILED CLOSE");
        exit(EXIT_FAILURE);
    }
}


int Setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len){
    if (setsockopt(socket, level, option_name, option_value, option_len) == -1){
        perror("SETSOCKOPT");
        exit(EXIT_FAILURE);
    }
}

